//
//  JavascriptApi.m
//  iPhone
//
//  Created by 华 鲁 on 11-8-3.
//  Copyright 2011年 __MyCompanyName__. All rights reserved.
//

#import "JavascriptApi.h"

static NSString *nsstring2unicodeescape(NSString *input)
{
    int len = [input length];
    int i = 0;
    NSMutableString *output = [NSMutableString stringWithCapacity:len * 6];
    while(i < len)
    {
        [output appendFormat:@"\\u%04x", [input characterAtIndex:i]]; 
        i ++;
    }
    return output;
}

@implementation JavascriptApi

@synthesize webView;


+ (NSMutableArray *) getArrayParam:(NSString *) param
{
    
    NSMutableArray *arr = [[[NSMutableArray alloc] init]autorelease];
    NSArray *items = [param componentsSeparatedByString:@":"];
    for (NSString *item in items)
    {
        [arr addObject:[item stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
    }
    return arr;
}

+ (NSMutableDictionary *) getDictParam:(NSString *) param
{
    NSMutableDictionary *dict = [[[NSMutableDictionary alloc] init]autorelease];
    NSArray *dictPairs = [param componentsSeparatedByString:@";"];
    for (NSString *dictPair in dictPairs)
    {
        NSArray *tmpArray = [dictPair componentsSeparatedByString:@":"];
        if ([tmpArray count] < 2) continue;
        NSString *key = (NSString *)[tmpArray objectAtIndex:0];
        NSString *value = (NSString *)[tmpArray objectAtIndex:1];
        key = [key stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        value = [value stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        [dict setObject:value forKey:key];
    }
    
    return dict;
}


- (void) dealloc
{
    [_delegates release];
    [super dealloc];
}

- (JavascriptApi *) initWithWebView:(UIWebView *)wview
{
    self = [super init];
    if (self) {
        self.webView = wview;
        _delegates = [[NSMutableDictionary alloc]init];
    }
    return (self);
}

- (void) setDelegate:(NSObject *)delegate forNamespace:(NSString *)ns
{
    [_delegates setValue:delegate forKey:ns];
}

- (NSString *) evalJS:(NSString *)cmd
{
    return [self.webView stringByEvaluatingJavaScriptFromString:cmd];
}

- (NSString *) callJSMethod:(NSString *)func withArgs:(NSMutableArray *)args
{
    NSMutableArray *params = nil;
    NSString *cmd = nil;
    
    if (args != nil)
    {
        params = [[NSMutableArray alloc] init];
        for (NSString * param in args)
        {
            [params addObject:nsstring2unicodeescape(param)];
        }
    }
    
    
    if (params == nil) {
        cmd = [NSString stringWithFormat:@"%@()", func];
    }
    else
    {
        cmd = [NSString stringWithFormat:@"%@(\"%@\")", func, [params componentsJoinedByString:@"\",\""]];
    }
    
    [params release];
    return [self evalJS:cmd];
}

- (BOOL) matchURL:(NSURL *)url
{
    NSLog(@"url:%@", url);
    if ([_delegates count] == 0) 
    {
        return NO;
    }
    
    NSString *path = [url absoluteString];
    NSLog(@"path %@", path);
    NSString *query = [url query];
    if (![path hasPrefix:JavascriptApiPath]) return NO;
    
    NSArray *paramPairs = [query componentsSeparatedByString:@"&"];
    if ([paramPairs count] == 0) return NO;
    NSString *namespace = nil;
    NSString *method_name = nil;
    NSMutableArray *method_params = [[[NSMutableArray alloc] init]autorelease];
    for (NSString *paramPair in paramPairs)
    {
        NSArray *paramArray = [paramPair componentsSeparatedByString:@"="];
        if ([paramArray count] < 2) continue;
        NSString *value = (NSString *)[paramArray objectAtIndex:1];
        value = [value stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        if (namespace == nil) {
            namespace = value;
        }
        else if (method_name == nil) {
            method_name = value;
        }
        else
        {
            [method_params addObject:[NSString stringWithString:value]];
        }
    }
    
    if (namespace == nil) return NO;
    if (method_name == nil) return NO;
    
    NSObject *delegate = [_delegates objectForKey:namespace];
    if (delegate == nil) return NO;
    
    method_name = [NSString stringWithFormat:@"jsCall:%@:", method_name];
    NSLog(@"method name:%@", method_name);
    NSLog(@"params:%@", method_params);
    
    
    SEL callback = NSSelectorFromString(method_name);
    
    if ([delegate respondsToSelector:callback])
    {
        [delegate performSelector:callback withObject:self withObject:method_params];
        return YES;
    }
    else
    {
        NSLog(@"cant find selector:%@", method_name);
        return NO;
    }
    
    return YES;
}
@end
